package com.ctyun.oos.cilent;

import com.amazonaws.AmazonClientException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.S3ClientOptions;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @Author：wk
 * @Create：2022/1/19/10:48
 * @Description：Oos对象存储（经典版天翼云）
 * @Version：1.0
 */
@Component
@Slf4j
public class OosClient {

    private final Environment environment;

//    访问秘钥ID
    private static final String ACCESS_KEY_ID = "b1e8ca37755ba5598fb2";
//    访问秘钥
    private static final String ACCESS_KEY_SECRET = "b0cf2ca861ea815102aff20e5141a7e1a09f205d";
//    oos资源端点 域名
    private static final String END_POINT = "https://oos-cn.ctyunapi.cn/";
//    private static final String END_POINT = "https://oos-ahwh.ctyunapi.cn/";
//    oss的桶
    private static final String BUCKET_NAME = "kouzi";

    /**
     * 文件保存路径
     */
    private String fileStorePath;

    public OosClient(Environment environment) {
        this.environment = environment;
    }

    /**
     * 初始化完成配置装配
     */
    @PostConstruct
    private void setFileStorePath() {
        String property = environment.getProperty("file.store.path");
        Assert.notNull(property, "must set fileStorePath");
        log.info("path: {}", property);
        fileStorePath = property;
    }


    /**
     * 配置客户端
     * @return
     */
    public AmazonS3 getClient() {
        ClientConfiguration clientConfig = new ClientConfiguration();
        clientConfig.setConnectionTimeout(30 * 1000);     //设置连接的超时时间，单位毫秒
        clientConfig.setSocketTimeout(30 * 1000);        //设置socket超时时间，单位毫秒
        clientConfig.setProtocol(Protocol.HTTP);        //设置http

        //负载是否参与签名、设置为参与
        S3ClientOptions options = new S3ClientOptions();
        options.setPayloadSigningEnabled(true);

        //创建client对象
        AmazonS3 ossClient = new AmazonS3Client(
                new PropertiesCredentials(ACCESS_KEY_ID, ACCESS_KEY_SECRET), clientConfig);

        // 设置endpoint
        ossClient.setEndpoint(END_POINT);


        //设置选项
        ossClient.setS3ClientOptions(options);
        return ossClient;
    }

    /**
     * 上传文件
     * @param fileContent 文件内容
     * @param remotePath 上传文件夹地址
     * @param fileName 文件名称
     * @return
     */
    public String uploadFile(InputStream fileContent, String remotePath, String fileName) {
        AmazonS3 oosClient = getClient();
        // 定义二级目录
        String path = null;
        if (remotePath != null) {
            String remoteFilePath = remotePath.substring(0, remotePath.length()).replaceAll("\\\\", "/") + "/";
            path = remoteFilePath + fileName;
        } else {
            path = fileName;
        }
        // 创建上传Object的Metadata
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setCacheControl("no-cache");
        objectMetadata.setHeader("Pragma", "no-cache");
        try {
            objectMetadata.setContentLength(fileContent.available());
            // 上传文件
            log.info("开始上传文件到oss");
            oosClient.putObject(BUCKET_NAME, path, fileContent, objectMetadata);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传文件到oss失败!Path:{}",path);
        } finally {
            if (oosClient != null) {
                ((AmazonS3Client) oosClient).shutdown();
            }
            if (fileContent != null) {
                try {
                    fileContent.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        log.info("上传文件到Oos成功！Path:{}",path);
        return path;
    }

    /**
     * 图片下载路径命名规则
     *
     * @param fileName 文件名称
     * @return 返回地址
     */
    private Path name2Path(String fileName) {
        //return Paths.get(fileStorePath, fileName.substring(0, 2), fileName.substring(2, 4), fileName);
        return Paths.get(fileStorePath, fileName);
    }

    /**
     * 获取文件 实现
     *
     * @param fileName 文件名称
     * @return 文件地址
     */
    private Path getFile(String fileName) {
        //获取文件保存路径
        Path path = name2Path(fileName);
        Assert.isTrue(Files.exists(path), "Invalid Filename " + fileName);
        return path;
    }

    /**
     * 下载文件
     * @param fileName 文件路径名称
     * @return
     */
    public String downloadFile(String fileName, HttpServletResponse response) {
        AmazonS3 oosClient = getClient();
        Path path = null;
        try {
            path = name2Path(fileName);
            //创建文件夹
            Files.createDirectories(path.getParent());
            // 下载文件
            log.info("开始下载图片");
            oosClient.getObject(new GetObjectRequest(BUCKET_NAME, fileName),
                    new File(path.toUri().getPath()));
//            预览需要
            Files.copy(getFile(fileName), response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("下载文件失败");
        } finally {
            if (oosClient != null) {
                ((AmazonS3Client) oosClient).shutdown();
            }
        }
        log.info("图片下载成功！Path:{}",path.toUri().getPath());
        return fileName;
    }


    /**
     * 删除文件
     * @param filePath 文件路径地址
     * @param fileName 文件名称
     * @return
     */
    public boolean deleteFile(String filePath, String fileName) {
        AmazonS3 ossClient = getClient();
        // 定义二级目录
        String remoteFilePath = filePath.substring(0, filePath.length()).replaceAll("\\\\", "/") + "/";
        String path = remoteFilePath + fileName;
        boolean exist = ossClient.doesBucketExist(BUCKET_NAME);
        if (!exist) {
            log.error("从OSS存储删除的文件不存在,path={}", path);
            return false;
        } else {
            try {
                ossClient.deleteObject(BUCKET_NAME, path);
            } catch (Exception e) {
                log.error("从天翼云OSS删除文件出错,path={}", path, e);
                return false;
            } finally {
                if (ossClient != null) {
                    try {
                        ((AmazonS3Client) ossClient).shutdown();
                    } catch (AmazonClientException e) {
                        e.printStackTrace();
                    }
                }
            }
            return true;
        }
    }

}
